#include <linux/sched.h>
#include <linux/sched/task.h>
#include <linux/refcount.h>

#include "inc/put_struct.h"

struct task_struct *get_task_struct(struct task_struct *t)
{
    refcount_inc(&t->usage);

    return t;
}

void put_task_struct(struct task_struct *t)
{
	if (!refcount_dec_and_test(&t->usage))
		return;

	/*
	 * Under PREEMPT_RT, we can't call __put_task_struct
	 * in atomic context because it will indirectly
	 * acquire sleeping locks. The same is true if the
	 * current process has a mutex enqueued (blocked on
	 * a PI chain).
	 *
	 * In !RT, it is always safe to call __put_task_struct().
	 * Though, in order to simplify the code, resort to the
	 * deferred call too.
	 *
	 * call_rcu() will schedule __put_task_struct_rcu_cb()
	 * to be called in process context.
	 *
	 * __put_task_struct() is called when
	 * refcount_dec_and_test(&t->usage) succeeds.
	 *
	 * This means that it can't "conflict" with
	 * put_task_struct_rcu_user() which abuses ->rcu the same
	 * way; rcu_users has a reference so task->usage can't be
	 * zero after rcu_users 1 -> 0 transition.
	 *
	 * delayed_free_task() also uses ->rcu, but it is only called
	 * when it fails to fork a process. Therefore, there is no
	 * way it can conflict with __put_task_struct().
	 */
	__put_task_struct_rcu(t);
}

void put_task_stack(struct task_struct *tsk)
{

}
